﻿#include "MessageDispatcher.h"
#include "Game/BaseGameEntity.h"
#include "misc/FrameCounter.h"
#include "Game/EntityManager.h"
#include "Debug/DebugConsole.h"

using std::set;

MessageDispatcher* MessageDispatcher::Instance()
{
	static MessageDispatcher instance; 

	return &instance;
}

void MessageDispatcher::Discharge(BaseGameEntity* pReceiver, const Telegram& msg)
{
	if(! pReceiver->HandleMessage(msg))
	{
		//消息未被处理
#ifdef SHOW_MESSAGING_INFO
		debug_con << "消息未被处理" << "";
#endif
	}
}

void MessageDispatcher::DispatchMsg(double delay, int sender, int receiver, int msg, void* extra /* = NULL */)
{
	//得到接收者指针
	BaseGameEntity* pReceiver = EntityMgr->GetEntityFromID(receiver);

	//无接收者（即为空）则返回
	if (pReceiver == NULL)
	{
#ifdef SHOW_MESSAGING_INFO
		debug_con << "\n警告！ 接收者ID： " << receiver << " 没有被找到" << "";
#endif
		return;
	}

	//生成消息报文
	Telegram telegram(0, sender, receiver, msg, extra);

	//如果是非延迟消息
	if (delay <= 0.0)                                                        
	{
#ifdef SHOW_MESSAGING_INFO
		debug_con << "\n报文发送时间: " << TickCounter->GetCurrentFrame()
			<< " 由 " << sender << " 给 " << receiver 
			<< "。 消息内容是： " << msg << "";
#endif
		//发送
		Discharge(pReceiver, telegram);
	}
	//延迟消息
	else
	{
		double CurrentTime = TickCounter->GetCurrentFrame(); 

		telegram.DispatchTime = CurrentTime + delay;
		//插入到优先队列中
		PriorityQ.insert(telegram);   

#ifdef SHOW_MESSAGING_INFO
		debug_con << "\n延迟消息发送自： " << sender << " 接收时间： " 
			<< TickCounter->GetCurrentFrame() << " 给 " << receiver
			<< "。 消息内容是： " << msg << "";
#endif
	}
}

void MessageDispatcher::DispatchDelayedMessages()
{
	double CurrentTime = TickCounter->GetCurrentFrame();

	while( !PriorityQ.empty() &&
		(PriorityQ.begin()->DispatchTime < CurrentTime) &&
		(PriorityQ.begin()->DispatchTime > 0))
	{
		const Telegram& telegram = *PriorityQ.begin();

		BaseGameEntity* pReceiver = EntityMgr->GetEntityFromID(telegram.Receiver);

#ifdef SHOW_MESSAGING_INFO
		debug_con << "\n报文队列准备就绪: 发送给 " 
			<< pReceiver->ID() << "。 消息内容是： "<< telegram.Msg << "";
#endif

		Discharge(pReceiver, telegram);

		PriorityQ.erase(PriorityQ.begin());
	}
}